home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * DocumentADT.c
- *
- * Functions related to the Document Abstract Data Type
- *
- ****************************************************************************/
-
- #include "Structs.h"
-
- #include "Assertion.h"
- #include "DocumentADT.h"
- #include "ElementADT.h"
-
- #include "StringUtils.h"
-
- // -----------------------------------------------------------------------------------
- #pragma mark PRIVATE CONSTANTS
- // -----------------------------------------------------------------------------------
-
- static const short kLockDocumentReferences = true;
-
-
- // -----------------------------------------------------------------------------------
- #pragma mark PRIVATE VARIABLES
- // -----------------------------------------------------------------------------------
-
- static DocumentList fgDocumentList = nil;
- static OSErr fgError = noErr;
- static short fgDocumentNumber = 0;
-
-
- // -----------------------------------------------------------------------------------
- #pragma mark PRIVATE PROTOTYPES
- // -----------------------------------------------------------------------------------
- static OSErr CreateDocumentData (DocumentReference document, DocumentType documentType);
- static void FreeDocumentData (DocumentReference document);
- static void FreeDocument (DocumentReference document);
- static void SetDocumentStructID (DocumentReference document);
- static void SetDocumentNumber (DocumentReference document, short documentNumber);
- static Boolean DocumentListIsValid (DocumentList list);
- static Boolean DocumentIsValid (DocumentReference document);
- static Boolean IsEmpty (DocumentList list);
- static void Insert (DocumentList list, DocumentReference documentToInsert);
- static void Remove (DocumentReference document);
- static void Link (DocumentReference previous, DocumentReference next);
-
- /*****************************************************************************
- *
- * DocumentError PUBLIC
- *
- * Call to get the last error registered by the ADT
- *
- *****************************************************************************/
- OSErr DocumentError(void)
- {
- return fgError;
- }
-
-
- /*****************************************************************************
- *
- * GetDocumentList PUBLIC
- *
- * Returns the document list reference which is a static global local to the
- * document ADT.
- *
- *****************************************************************************/
- DocumentList GetDocumentList(void)
- {
- return fgDocumentList;
- }
-
-
- /*****************************************************************************
- *
- * CreateDocumentList PUBLIC
- *
- * Call during program startup time
- *
- *****************************************************************************/
- void CreateDocumentList(void)
- {
- Boolean success = false;
- DocumentList head = nil;
-
-
- head = (DocumentList) NewHandleClear(sizeof(DocumentRecord));
- fgError = MemError();
-
- success = ((head != nil) && (fgError == noErr));
-
- if (success)
- {
- if (kLockDocumentReferences)
- HLockHi((Handle)head);
-
- (**head).structID = kDocumentListID;
- }
-
- fgDocumentList = head;
- }
-
-
- /*****************************************************************************
- *
- * CreateDocument PUBLIC
- *
- * Call to create a new document structure in memory - usually on New or Open
- * In the case of open, you will need to initialize fields in your client code
- *
- *****************************************************************************/
- DocumentReference CreateDocument(DocumentList list, DocumentType documentType)
- {
- OSErr error;
- DocumentReference document;
-
- document = (DocumentReference) NewHandleClear(sizeof (DocumentRecord));
- error = MemError();
-
- if (error == noErr) // Initialize all heap internal data here
- {
- if (kLockDocumentReferences)
- HLockHi((Handle) document);
-
- SetDocumentStructID(document);
- SetDocumentNumber(document, ++fgDocumentNumber);
- SetDocumentType(document, documentType);
-
- error = CreateDocumentData(document, documentType);
- }
-
-
- if (error == noErr) // insert the new record into the list
- Insert(list, document);
- else
- {
- FreeDocumentData(document);
- FreeDocument(document);
- }
-
- fgError = error;
-
- return document;
- }
-
-
- /*****************************************************************************
- *
- * CountDocuments PUBLIC
- *
- * Returns the number of documents contained in a specified document list.
- *
- *****************************************************************************/
- short CountDocuments(DocumentList list)
- {
- DocumentReference document = nil;
- short count = 0;
-
- if (DocumentListIsValid(list))
- {
- document = GetFirstDocument(list);
-
- while (document != nil && DocumentIsValid(document))
- {
- count++;
- document = GetDocumentNextDocument(document);
- }
- }
-
- return count;
- }
-
-
- /*****************************************************************************
- *
- * DestroyDocumentList PUBLIC
- *
- * Call at program shutdown time to delete all documents, from head to tail
- *
- *****************************************************************************/
- void DestroyDocumentList(DocumentList list)
- {
- DocumentReference document;
-
- if (DocumentListIsValid(list))
- {
- document = GetFirstDocument(list);
-
- while (document != nil)
- {
- DestroyDocument(document);
- document = GetFirstDocument(list);
- }
-
- DisposeHandle((Handle)list);
- }
- }
-
-
- /*****************************************************************************
- *
- * DestroyDocument PUBLIC
- *
- * Call when an document document is closed
- *
- *****************************************************************************/
- void DestroyDocument(DocumentReference document)
- {
- if (DocumentIsValid(document))
- {
- Remove(document);
- FreeDocumentData(document);
- FreeDocument(document);
- }
- }
-
-
- /*****************************************************************************
- *
- * GetFirstDocument PUBLIC
- *
- * Call to get a reference to the first document in an document list
- * Use with GetNextDocument() to walk the document list
- *
- *****************************************************************************/
- DocumentReference GetFirstDocument(DocumentList list)
- {
- DocumentReference head = (DocumentReference)list;
- DocumentReference first = nil;
-
- if (DocumentListIsValid(list))
- {
- first = (**head).next;
- }
-
- return first;
- }
-
-
- /*****************************************************************************
- *
- * GetLastDocument PUBLIC
- *
- * Call to get a reference to the last document in an document list
- *
- *****************************************************************************/
- DocumentReference GetLastDocument(DocumentList list)
- {
- DocumentReference last = GetFirstDocument(list);
-
- if (last != nil) {
- while (GetDocumentNextDocument(last) != nil) {
- last = GetDocumentNextDocument(last);
- }
- }
-
- return last;
- }
-
-
- /*****************************************************************************
- *
- * CreateDocumentData PRIVATE
- *
- * Set up a new document record with reasonable values.
- *
- * It is the responsibility of the caller to populate the window reference.
- *
- *****************************************************************************/
- static OSErr CreateDocumentData(DocumentReference document, DocumentType documentType)
- {
- #pragma unused (documentType)
-
- OSErr error = noErr;
- ElementList list;
-
- SetDocumentNumberOfChanges (document, 0);
- SetDocumentMaxWidth (document, 600);
- SetDocumentMaxHeight (document, 300);
-
- list = CreateElementList();
-
- if (list != nil)
- SetDocumentElementList(document, list);
- else
- error = memFullErr;
-
-
- return error;
- }
-
-
- /*****************************************************************************
- *
- * FreeDocumentData PRIVATE
- *
- * Dispose of all memory allocated and stored inside this document, but not
- * the document itself
- *
- *****************************************************************************/
- static void FreeDocumentData(DocumentReference document)
- {
- WindowPtr window;
-
- window = GetDocumentWindow(document);
- // if (window != nil)
- // HideWindow(window);
-
- SetDocumentWindow(document, nil); // This disposes of the existing window
- }
-
-
- /*****************************************************************************
- *
- * FreeDocument PRIVATE
- *
- * Dispose the document record. You should have already called
- * FreeDocumentData() on the document.
- *
- *****************************************************************************/
- static void FreeDocument(DocumentReference document)
- {
- if (DocumentIsValid(document))
- {
- if (kLockDocumentReferences == true)
- HUnlock((Handle)document);
-
- DisposeHandle((Handle)document);
- }
- }
-
-
- /*****************************************************************************
- *
- * SetDocumentStructID PRIVATE
- *
- * For debugging, we store a "magic cookie" in the first data member
- *
- *****************************************************************************/
- static void SetDocumentStructID(DocumentReference document)
- {
- (**document).structID = kDocumentRecordID;
- }
-
-
- /*****************************************************************************
- *
- * SetDocumentNumber PRIVATE
- *
- * Assign a sequential number for all documents created.
- *
- *****************************************************************************/
- static void SetDocumentNumber(DocumentReference document, short documentNumber)
- {
- (**document).documentNumber = documentNumber;
- }
-
-
- /*****************************************************************************
- *
- * DocumentListIsValid PRIVATE
- *
- * Returns true if specified document list is valid. This is useful for debugging.
- *
- *****************************************************************************/
- static Boolean DocumentListIsValid(DocumentList list)
- {
- DocumentReference head = (DocumentReference) list;
- Boolean isValid = (head != nil);
-
- if (isValid)
- {
- isValid = ((**head).structID == kDocumentListID);
- }
-
- Assert(isValid, "An invalid document list has been detected.");
-
- return isValid;
- }
-
-
- /*****************************************************************************
- *
- * DocumentIsValid PRIVATE
- *
- * returns true if specified document is valid. This is useful for debugging.
- *
- *****************************************************************************/
- static Boolean DocumentIsValid(DocumentReference document)
- {
- Boolean isValid = (document != nil);
-
- if (isValid)
- isValid = ((**document).structID == kDocumentRecordID);
-
- Assert(isValid, "An invalid document has been detected.");
-
- return isValid;
- }
-
- /*****************************************************************************
- *
- * IsEmpty PRIVATE
- *
- * Returns true if the list contains no documents
- *
- *****************************************************************************/
- static Boolean IsEmpty(DocumentList list)
- {
- return GetFirstDocument(list) == nil;
- }
-
-
- /*****************************************************************************
- *
- * Insert PRIVATE
- *
- * Insert a document into the list, implemented by appending the document.
- *
- *****************************************************************************/
- static void Insert(DocumentList list, DocumentReference documentToInsert)
- {
- DocumentReference document;
-
- if (IsEmpty(list))
- document = (DocumentReference) list;
- else
- document = GetLastDocument(list);
-
- Link(document, documentToInsert);
- }
-
-
- /*****************************************************************************
- *
- * Remove PRIVATE
- *
- * Remove a document from any list. Does NOT delete the document from memory.
- *
- *****************************************************************************/
- static void Remove(DocumentReference document)
- {
- DocumentReference previous = GetDocumentPreviousDocument(document);
- DocumentReference next = GetDocumentNextDocument(document);
-
- Link(previous, next);
-
- (**document).previous = nil;
- (**document).next = nil;
- }
-
-
- /*****************************************************************************
- *
- * Link PRIVATE
- *
- * Establish a 2-way link between two documents
- *
- *****************************************************************************/
- static void Link(DocumentReference previous, DocumentReference next)
- {
- (**previous).next = next;
-
- if (next != nil)
- (**next).previous = previous;
- }
-
- // --------------------------------------------------------------------------
-
-
- short GetDocumentNumber(DocumentReference document)
- {
- return (**document).documentNumber;
- }
-
- // --------------------------------------------------------------------------
-
- DocumentType GetDocumentType(DocumentReference document)
- {
- return (**document).documentType;
- }
-
- // --------------------------------------------------------------------------
-
- void GetDocumentName(DocumentReference document, StringPtr documentName)
- {
- PStringCopy((**document).documentName, documentName);
- }
-
- // --------------------------------------------------------------------------
-
- DocumentReference GetDocumentNextDocument(DocumentReference document)
- {
- return (**document).next;
- }
-
- // --------------------------------------------------------------------------
-
- DocumentReference GetDocumentPreviousDocument(DocumentReference document)
- {
- return (**document).previous;
- }
-
- // --------------------------------------------------------------------------
-
- WindowPtr GetDocumentWindow(DocumentReference document)
- {
- return (**document).window;
- }
-
- // --------------------------------------------------------------------------
-
- ElementList GetDocumentElementList(DocumentReference document)
- {
- return (**document).elementList;
- }
-
- // --------------------------------------------------------------------------
-
- short GetDocumentMaxWidth(DocumentReference document)
- {
- return (**document).maxWidth;
- }
-
- // --------------------------------------------------------------------------
-
- short GetDocumentMaxHeight(DocumentReference document)
- {
- return (**document).maxHeight;
- }
-
- // --------------------------------------------------------------------------
-
- unsigned short GetDocumentNumberOfChanges(DocumentReference document)
- {
- return (**document).numberOfChanges;
- }
-
-
- // --------------------------------------------------------------------------
-
- void SetDocumentType(DocumentReference document, DocumentType documentType)
- {
- (**document).documentType = documentType;
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentName(DocumentReference document, ConstStr63Param documentName)
- {
- PStringCopy((StringPtr) documentName, (**document).documentName);
-
- if ((**document).window != nil)
- {
- SetWTitle((WindowPtr) (**document).window, documentName);
- }
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentNextDocument(DocumentReference document, DocumentReference next)
- {
- (**document).next = next;
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentPreviousDocument(DocumentReference document, DocumentReference previous)
- {
- (**document).previous = previous;
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentNumberOfChanges(DocumentReference document, unsigned short numberOfChanges)
- {
- (**document).numberOfChanges = numberOfChanges;
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentWindow(DocumentReference document, WindowPtr window)
- {
- WindowPtr existingWindow;
-
- existingWindow = (**document).window;
-
- if (existingWindow != window) // are they different
- if (existingWindow != nil) // is it currently non-nil?
- DisposeWindow(existingWindow);
-
- (**document).window = window;
-
- if (window != nil)
- {
- SetWRefCon((WindowPtr) window, (long) document);
- }
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentElementList(DocumentReference document, ElementList list)
- {
- ElementList existingList = (**document).elementList;
-
- /*
- if (existingWindow != list) // are they different
- if (existingList != nil) // is it currently non-nil?
- DisposeWindow(existingWindow);
- */
-
- (**document).elementList = list;
-
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentMaxWidth(DocumentReference document, short maxWidth)
- {
- (**document).maxWidth = maxWidth;
- }
-
- // --------------------------------------------------------------------------
-
- void SetDocumentMaxHeight(DocumentReference document, short maxHeight)
- {
- (**document).maxHeight = maxHeight;
- }
-
-
- // --------------------------------------------------------------------------
-
-
-